﻿using System;
using sn.Models;
using System.IO;
using System.Collections;
using System.Collections.Generic;

namespace sn
{
    class Program
    {

        static string getRelativePath(string fromDirectory, string toPath)
        {
            if (fromDirectory == null)
                throw new ArgumentNullException("fromDirectory");

            if (toPath == null)
                throw new ArgumentNullException("toPath");

            bool isRooted = (Path.IsPathRooted(fromDirectory) && Path.IsPathRooted(toPath));

            if (isRooted)
            {
                bool isDifferentRoot = (string.Compare(Path.GetPathRoot(fromDirectory), Path.GetPathRoot(toPath), true) != 0);

                if (isDifferentRoot)
                    return toPath;
            }

            List<string> relativePath = new List<string>();
            string[] fromDirectories = fromDirectory.Split(Path.DirectorySeparatorChar);

            string[] toDirectories = toPath.Split(Path.DirectorySeparatorChar);

            int length = Math.Min(fromDirectories.Length, toDirectories.Length);

            int lastCommonRoot = -1;

            // find common root
            for (int x = 0; x < length; x++)
            {
                if (string.Compare(fromDirectories[x], toDirectories[x], true) != 0)
                    break;

                lastCommonRoot = x;
            }

            if (lastCommonRoot == -1)
                return toPath;

            // add relative folders in from path
            for (int x = lastCommonRoot + 1; x < fromDirectories.Length; x++)
            {
                if (fromDirectories[x].Length > 0)
                    relativePath.Add("..");
            }

            // add to folders to path
            for (int x = lastCommonRoot + 1; x < toDirectories.Length; x++)
            {
                relativePath.Add(toDirectories[x]);
            }

            // create relative path
            string[] relativeParts = new string[relativePath.Count];
            relativePath.CopyTo(relativeParts, 0);

            string newPath = string.Join(Path.DirectorySeparatorChar.ToString(), relativeParts);

            return newPath;
        }


        static void Main(string[] args)
        {
            // Console.WriteLine(Directory.GetCurrentDirectory());
            // var str = getRelativePath(Directory.GetCurrentDirectory(),
            //     @"‪D:\code\sn\sn\DaoFolder.cs");
            // Console.WriteLine(str);

            // return;


            string dir = Directory.GetCurrentDirectory();

            if(args.Length>0 && args[0]=="drop"){
                //Console.WriteLine(args[0]);
                try {
                    DaoPath.drop_tbl();
                    DaoFolder.drop_tbl();
                    Console.WriteLine("drop table success");
                } catch {}
                return;
            }

            bool toRevert = false;

            if(args.Length>0 && args[0]=="revert"){
                //Console.WriteLine(args[0]);
                toRevert = true;
            } 

            if(toRevert){
                Console.WriteLine("revert start");

                DirectoryInfo TheFolderR=new DirectoryInfo(dir);
                foreach(FileInfo NextFile in TheFolderR.GetFiles()){                
                    dealDetailR(NextFile);                
                }

                foreach(DirectoryInfo NextFolder in TheFolderR.GetDirectories()){
                    bool exi = DaoFolder.exists_new(NextFolder.Name);
                    if(exi){
                        string old_name = DaoFolder.get_old_name(NextFolder.Name);
                        string old_name_full = System.IO.Path.Combine(dir,old_name);
                        System.IO.Directory.Move(NextFolder.FullName,old_name_full);
                    }
                }

                foreach(DirectoryInfo NextFolder in TheFolderR.GetDirectories()){
                    Console.WriteLine(NextFolder.Name+"");
                    detailR(NextFolder.FullName);
                }


                Console.WriteLine("revert end");
                return;
            }

            try {
                if(DaoPath.table_exists()==false){
                    DaoPath.create_tbl();
                    Console.WriteLine("create path_tbl");
                }        
                      
            } catch {}
            
            try {
                if(DaoFolder.table_exists()==false){
                    DaoFolder.create_tbl();
                    Console.WriteLine("create folder_tbl");
                } 
            } catch {}
                     
          //  Console.WriteLine(dir);

            string folderFullName = dir;
            DirectoryInfo TheFolder=new DirectoryInfo(folderFullName);
            //目录下文件
            foreach(FileInfo NextFile in TheFolder.GetFiles()){                
                dealDetail(NextFile);                
            }

            //子目录下文件
            foreach(DirectoryInfo NextFolder in TheFolder.GetDirectories()){
                Console.WriteLine(NextFolder.Name+"");
                detail(NextFolder.FullName);
            }

            //目录
            //TODO
            foreach(DirectoryInfo NextFolder in TheFolder.GetDirectories()){
                Console.WriteLine(NextFolder.Name+"");
                
                bool exi = DaoFolder.exists_ori(NextFolder.Name);
                if(exi){
                    string new_name = DaoFolder.get_new_name(NextFolder.Name);
                    string new_name_full_path = System.IO.Path.Combine(dir,new_name);
                    if(!System.IO.Directory.Exists(new_name_full_path)){
                        System.IO.Directory.Move(NextFolder.Name,new_name);
                    }
                } else {
                    var new_name = genGuid();
                    DaoFolder.insert(new_name,NextFolder.Name);
                    System.IO.Directory.Move(NextFolder.Name,new_name);
                }                

            }
            

            Console.WriteLine();
            
        }

        static void dealDetailR(FileInfo NextFile){
            Console.WriteLine(NextFile.DirectoryName);
            Console.WriteLine(NextFile.Name);

            string dir = Directory.GetCurrentDirectory();
            string relative_dir = getRelativePath(dir,NextFile.DirectoryName);

            bool exists = DaoPath.exists_new(relative_dir,NextFile.Name);
            if(exists){
                string old_path = DaoPath.get_old_name(relative_dir,NextFile.Name);
                string old_path_full = System.IO.Path.Combine(NextFile.DirectoryName,old_path);
                System.IO.File.Move(NextFile.FullName,old_path_full);

                Console.WriteLine("convert成功"+NextFile.FullName);
            }                               
        }

        static void dealDetail(FileInfo NextFile){
            
            string dir = Directory.GetCurrentDirectory();
            //  todo
            Console.WriteLine(NextFile.DirectoryName);
                Console.WriteLine(NextFile.Name);

                if(NextFile.Name=="sn.sqlite3.db"){
                    return;
                }
                if(NextFile.Name=="sn.exe"){
                    return;
                }
                if(NextFile.Name=="sn.pdb"){
                    return;
                }

                string relative_dir = getRelativePath(dir,NextFile.DirectoryName);
                bool exists = DaoPath.exists_ori(relative_dir,NextFile.Name);
                if(exists){
                    Console.WriteLine("文件已经存在"+NextFile.FullName);
                    string new_name = DaoPath.get_new_name(relative_dir,NextFile.Name);
                    string new_name_full_path = System.IO.Path.Combine(NextFile.DirectoryName,new_name);
                    if(!System.IO.File.Exists(new_name_full_path)){
                        System.IO.File.Move(NextFile.FullName,new_name_full_path);
                    }
                }
                
                if(exists==false){

                    exists = DaoPath.exists_new(relative_dir,NextFile.Name);
                    if(exists){
                        //已经转换过
                    } else {

                        var new_name = genGuid();
                        DaoPath.insert(relative_dir,new_name,NextFile.Name);
                        Console.WriteLine("insert "+NextFile.FullName);
                        var new_name_full_path = System.IO.Path.Combine(NextFile.DirectoryName,new_name);
                        System.IO.File.Move(NextFile.FullName,new_name_full_path);

                    }
                    
                }
        }


         static void detail(string folder){
            DirectoryInfo TheFolder=new DirectoryInfo(folder);
            foreach(FileInfo NextFile in TheFolder.GetFiles()){
                dealDetail(NextFile);        
            }
        }

        static void detailR(string folder){
            DirectoryInfo TheFolder=new DirectoryInfo(folder);
            foreach(FileInfo NextFile in TheFolder.GetFiles()){
                dealDetailR(NextFile);                
            }
        }

        public static string genGuid(){
            var uuidN = Guid.NewGuid().ToString("N");
            return uuidN;
        }
    }
}
